//  
//  Copyright © 2009 Jiří Zárevúcky <zarevucky.jiri@gmail.com>
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
// 
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
// 
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
// 

using System;
using System.Collections.Generic;
using Gtk;

using Galaxium.Protocol.Xmpp.Library;
using L=Galaxium.Protocol.Xmpp.Library;
using Galaxium.Protocol.Xmpp.Library.Xml;
using Galaxium.Protocol.Xmpp.Library.Extensions;

// TODO: cut Client dependency

namespace Galaxium.Protocol.Xmpp.GtkGui
{
	public class ElementEventArgs: EventArgs
	{
		public ElementEventArgs (Element elm)
		{
			Element = elm;
		}
		
		public Element Element { get; private set; }
	}
	
	public class DataFormWidget: Table
	{
		public DataFormWidget (L.Client client, DataForm form)
			:base (1, 1, false)
		{
			_client = client;

			base.BorderWidth = 12;
			base.RowSpacing = 6;
			base.ColumnSpacing = 12;
			
			Title = form.Title;

			if (!String.IsNullOrEmpty (form.Instructions)) {
				var instructions = new Label ();
				instructions.Markup = "<b>" + GLib.Markup.EscapeText (form.Instructions) + "</b>";
				instructions.Xalign = 0.0f;
				this.Attach (instructions, 0, 3, _index, ++ _index,
				             AttachOptions.Fill, AttachOptions.Fill, 0, 12);
			}
			
			foreach (var field in form)
				AddField (field);

			this.ShowAll ();
		}

		public string Title { get; private set; }

		private void AddField (DataField field)
		{
			if (field.Type == DataFieldType.Hidden) return;
			if (field.Type == DataFieldType.Fixed) {
				var label = new Label ();
				label.Markup = "<b>" +
					GLib.Markup.EscapeText (field.GetString () ?? String.Empty) + "</b>";
				label.TooltipText = field.Description;
				label.Xalign = 0.0f;
				this.Attach (label, 0, 3, _index, _index + 1,
				             AttachOptions.Fill, AttachOptions.Fill, 0, 0);
			}
			else {
				if (field.Type != DataFieldType.Boolean) {
					var label = new Label (field.Label ?? field.Identifier + ":");
					label.TooltipText = field.Description;
					label.Xalign = 0.0f;
					if (field.Type == DataFieldType.JidMulti
					    || field.Type == DataFieldType.ListMulti
					    || field.Type == DataFieldType.TextMulti)
						label.Yalign = 0.0f;
					this.Attach (label, 0, 1, _index, _index + 1,
					             AttachOptions.Fill, AttachOptions.Fill, 0, 0);
				}
				
				var widget = new DataFieldWidget (_client, field);
				this.Attach (widget, 1, 2, _index, _index + 1,
				             AttachOptions.Expand | AttachOptions.Fill, AttachOptions.Fill, 0, 0);
				if (field.IsRequired) {
					var img = new Image (Stock.DialogWarning, IconSize.Menu);
					img.TooltipText = "This field is required.";
					this.Attach (img, 2, 3, _index, _index + 1, 0, 0, 0, 0);
				}
			}
			_index ++;
		}
		
		private L.Client _client;
		private uint _index;
		
		public void Clear ()
		{
			foreach (var child in this.Children)
				if (child is DataFieldWidget) (child as DataFieldWidget).Clear ();
		}
	}
}
